use core::fmt;
use std::error::Error;

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Color<T> {
    pub r: T,
    pub g: T,
    pub b: T,
    pub a: T,
}

impl<T: Copy + HasMaxValue> Color<T> {
    pub const fn new_rgba(r: T, g: T, b: T, a: T) -> Self {
        Self { r, g, b, a }
    }

    pub const fn new_rgb(r: T, g: T, b: T) -> Self {
        Self {
            r,
            g,
            b,
            a: T::MAX_VALUE,
        }
    }

    pub const fn with_alpha(self, alpha: T) -> Self {
        Self {
            r: self.r,
            g: self.g,
            b: self.b,
            a: alpha,
        }
    }
}

impl Color<u8> {
    pub fn to_srgb(&self) -> Color<u8> {
        fn srgb_comp(v: f32) -> u8 {
            let linear = v / 255.0;
            let srgb = if linear <= 0.0031308 {
                linear * 12.92
            } else {
                1.055 * linear.powf(1.0 / 2.4) - 0.055
            };
            (srgb * 255.0).round() as u8
        }

        Color {
            r: srgb_comp(self.r as f32),
            g: srgb_comp(self.g as f32),
            b: srgb_comp(self.b as f32),
            a: self.a,
        }
    }

    #[inline]
    pub const fn to_f32(self) -> Color<f32> {
        Color {
            r: self.r as f32 / 255.0,
            g: self.g as f32 / 255.0,
            b: self.b as f32 / 255.0,
            a: self.a as f32 / 255.0,
        }
    }

    #[inline]
    pub const fn to_f64(self) -> Color<f64> {
        Color {
            r: self.r as f64 / 255.0,
            g: self.g as f64 / 255.0,
            b: self.b as f64 / 255.0,
            a: self.a as f64 / 255.0,
        }
    }

    /// 将sRGB颜色转换为线性颜色
    /// sRGB颜色：0到255之间的整数
    /// 线性颜色：0.0到1.0之间的浮点数
    #[inline]
    pub fn to_linear(self) -> Color<f64> {
        #[inline]
        fn srgb_to_linear(channel: u8) -> f64 {
            let c = channel as f64 / 255.0;
            if c <= 0.04045 {
                c / 12.92
            } else {
                ((c + 0.055) / 1.055).powf(2.4)
            }
        }

        Color {
            r: srgb_to_linear(self.r),
            g: srgb_to_linear(self.g),
            b: srgb_to_linear(self.b),
            a: self.a as f64 / 255.0,
        }
    }
}

impl Color<f32> {
    pub fn to_srgb(&self) -> Color<f32> {
        fn srgb_comp(v: f32) -> f32 {
            if v <= 0.0031308 {
                v * 12.92
            } else {
                1.055 * v.powf(1.0 / 2.4) - 0.055
            }
        }

        Color {
            r: srgb_comp(self.r),
            g: srgb_comp(self.g),
            b: srgb_comp(self.b),
            a: self.a,
        }
    }

    #[inline]
    pub const fn to_u8(self) -> Color<u8> {
        Color {
            r: (self.r * 255.0) as u8,
            g: (self.g * 255.0) as u8,
            b: (self.b * 255.0) as u8,
            a: (self.a * 255.0) as u8,
        }
    }

    #[inline]
    pub const fn to_f64(self) -> Color<f64> {
        Color {
            r: self.r as f64,
            g: self.g as f64,
            b: self.b as f64,
            a: self.a as f64,
        }
    }

    /// 将sRGB颜色转换为线性颜色
    /// sRGB颜色：0.0到1.0之间的浮点数
    /// 线性颜色：0.0到1.0之间的浮点数
    #[inline]
    pub fn to_linear(self) -> Color<f64> {
        #[inline]
        fn srgb_to_linear(channel: f32) -> f64 {
            let c = channel as f64;
            if c <= 0.04045 {
                c / 12.92
            } else {
                ((c + 0.055) / 1.055).powf(2.4)
            }
        }

        Color {
            r: srgb_to_linear(self.r),
            g: srgb_to_linear(self.g),
            b: srgb_to_linear(self.b),
            a: self.a as f64,
        }
    }
}

impl Color<f64> {
    pub fn to_srgb(&self) -> Color<f64> {
        fn srgb_comp(v: f64) -> f64 {
            if v <= 0.0031308 {
                v * 12.92
            } else {
                1.055 * v.powf(1.0 / 2.4) - 0.055
            }
        }

        Color {
            r: srgb_comp(self.r),
            g: srgb_comp(self.g),
            b: srgb_comp(self.b),
            a: self.a,
        }
    }

    #[inline]
    pub const fn to_u8(self) -> Color<u8> {
        Color {
            r: (self.r * 255.0) as u8,
            g: (self.g * 255.0) as u8,
            b: (self.b * 255.0) as u8,
            a: (self.a * 255.0) as u8,
        }
    }
    #[inline]

    pub const fn to_f32(self) -> Color<f32> {
        Color {
            r: self.r as f32,
            g: self.g as f32,
            b: self.b as f32,
            a: self.a as f32,
        }
    }

    /// 将线性颜色转换为sRGB颜色
    /// 线性颜色：0.0到1.0之间的浮点数
    /// sRGB颜色：0到255之间的整数
    #[inline]
    pub fn to_linear(self) -> Self {
        #[inline]
        fn linear_to_srgb(channel: f64) -> f64 {
            if channel <= 0.0031308 {
                channel * 12.92
            } else {
                1.055 * channel.powf(1.0 / 2.4) - 0.055
            }
        }

        Self {
            r: linear_to_srgb(self.r),
            g: linear_to_srgb(self.g),
            b: linear_to_srgb(self.b),
            a: self.a,
        }
    }
}

impl<T: ColorComponent> Color<T> {
    pub const fn from_rgb(r: T, g: T, b: T) -> Self {
        Self {
            r,
            g,
            b,
            a: T::MAX_VALUE,
        }
    }

    pub const fn from_rgba(r: T, g: T, b: T, a: T) -> Self {
        Self { r, g, b, a }
    }

    // 从十六进制数字创建（修改为泛型版本）
    pub fn from_hex(hex: u32) -> Result<Self, ColorError> {
        // 提取 RGBA 分量（始终从 32 位值解析）
        let a = (hex >> 24) & 0xFF;
        let r = (hex >> 16) & 0xFF;
        let g = (hex >> 8) & 0xFF;
        let b = hex & 0xFF;

        // 根据目标类型转换分量
        Ok(Self {
            r: T::from_hex_byte(r as u8),
            g: T::from_hex_byte(g as u8),
            b: T::from_hex_byte(b as u8),
            a: if hex > 0xFFFFFF {
                T::from_hex_byte(a as u8)
            } else {
                T::MAX_VALUE
            },
        })
    }

    // 从字符串创建（修改为泛型版本）
    pub fn from_str(s: &str) -> Result<Self, ColorError> {
        let s = s.trim_start_matches('#');
        let hex = u32::from_str_radix(s, 16).map_err(|_| ColorError::ParseError)?;

        match s.len() {
            6 => Self::from_hex(hex | 0xFF000000), // 添加默认 alpha
            8 => Self::from_hex(hex),
            _ => Err(ColorError::InvalidStringLength),
        }
    }

    // 转换为 RGB 数组
    pub fn to_rgb(&self) -> [T; 3] {
        [self.r, self.g, self.b]
    }

    // 转换为 RGBA 数组
    pub fn to_rgba(&self) -> [T; 4] {
        [self.r, self.g, self.b, self.a]
    }

    // 转换为十六进制数字（支持不同类型输出）
    pub fn to_hex(&self) -> u32 {
        let r = (self.r.to_f32() * 255.0) as u32;
        let g = (self.g.to_f32() * 255.0) as u32;
        let b = (self.b.to_f32() * 255.0) as u32;
        let a = (self.a.to_f32() * 255.0) as u32;
        (a << 24) | (r << 16) | (g << 8) | b
    }

    // 转换为字符串
    pub fn to_string(&self) -> String {
        format!(
            "#{:02X}{:02X}{:02X}{:02X}",
            (self.r.to_f32() * 255.0) as u8,
            (self.g.to_f32() * 255.0) as u8,
            (self.b.to_f32() * 255.0) as u8,
            (self.a.to_f32() * 255.0) as u8
        )
    }
}

#[derive(Debug)]
pub enum ColorError {
    InvalidHex,
    InvalidStringLength,
    ParseError,
}

impl fmt::Display for ColorError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            ColorError::InvalidHex => write!(f, "Invalid hexadecimal value"),
            ColorError::InvalidStringLength => write!(f, "Invalid string length for color"),
            ColorError::ParseError => write!(f, "Failed to parse color"),
        }
    }
}

// impl entry..
pub trait ColorComponent: Copy + Clone + PartialEq + HasMaxValue {
    fn from_u8(value: u8) -> Self;
    fn from_f32(value: f32) -> Self;
    fn to_f32(&self) -> f32;
    fn from_hex_byte(byte: u8) -> Self;
}

impl ColorComponent for u8 {
    fn from_f32(value: f32) -> Self {
        (value * 255.0).clamp(0.0, 255.0) as Self
    }
    fn to_f32(&self) -> f32 {
        *self as f32 / 255.0
    }
    fn from_hex_byte(byte: u8) -> Self {
        byte
    }

    fn from_u8(value: u8) -> Self {
        value
    }
}

impl ColorComponent for u16 {
    fn from_f32(value: f32) -> Self {
        (value * 65535.0).clamp(0.0, 65535.0) as Self
    }
    fn to_f32(&self) -> f32 {
        *self as f32 / 65535.0
    }
    fn from_hex_byte(byte: u8) -> Self {
        (byte as u16) << 8 | byte as u16
    }

    fn from_u8(value: u8) -> Self {
        value as u16
    }
}

impl ColorComponent for f32 {
    fn from_f32(value: f32) -> Self {
        value.clamp(0.0, 1.0)
    }
    fn to_f32(&self) -> f32 {
        *self
    }
    fn from_hex_byte(byte: u8) -> Self {
        byte as f32 / 255.0
    }

    fn from_u8(value: u8) -> Self {
        value as f32 / 255.0
    }
}

impl ColorComponent for f64 {
    fn from_f32(value: f32) -> Self {
        value as f64
    }
    fn to_f32(&self) -> f32 {
        *self as f32
    }
    fn from_hex_byte(byte: u8) -> Self {
        byte as f64 / 255.0
    }

    fn from_u8(value: u8) -> Self {
        value as f64 / 255.0
    }
}

// Default Colors
impl Color<u8> {
    /* 通用风格 */
    /// 国际黑 #000000
    pub const G_BLACK: Self = Self::from_rgb(0, 0, 0);
    /// 国际白 #FFFFFF
    pub const G_WHITE: Self = Self::from_rgb(255, 255, 255);
    /// 国际红 #FF0000
    pub const G_RED: Self = Self::from_rgb(255, 0, 0);
    /// 国际绿 #00FF00
    pub const G_GREEN: Self = Self::from_rgb(0, 255, 0);
    /// 国际蓝 #0000FF
    pub const G_BLUE: Self = Self::from_rgb(0, 0, 255);
    /// 国际黄 #FFFF00
    pub const G_YELLOW: Self = Self::from_rgb(255, 255, 0);

    /* 中式风格 */
    /// 花萼绿 #014946
    pub const CN_CALYX_GREEN: Self = Self::from_rgb(1, 73, 70);
    /// 蓝灰色 #a1afc9
    pub const CN_LAN_HUI: Self = Self::from_rgb(161, 175, 201);

    // 其他u8颜色常量...
}

impl Color<f32> {
    /* 通用风格 */
    /// 国际黑 #000000
    pub const G_BLACK: Self = Color::<u8>::G_BLACK.to_f32();
    /// 国际白 #FFFFFF
    pub const G_WHITE: Self = Color::<u8>::G_WHITE.to_f32();
    /// 国际红 #FF0000
    pub const G_RED: Self = Color::<u8>::G_RED.to_f32();
    /// 国际绿 #00FF00
    pub const G_GREEN: Self = Color::<u8>::G_GREEN.to_f32();
    /// 国际蓝 #0000FF
    pub const G_BLUE: Self = Color::<u8>::G_BLUE.to_f32();
    /// 国际黄 #FFFF00
    pub const G_YELLOW: Self = Color::<u8>::G_YELLOW.to_f32();

    /* 中式风格 */
    /// 花萼绿 #014946
    pub const CN_CALYX_GREEN: Self = Color::<u8>::CN_CALYX_GREEN.to_f32();
    /// 蓝灰色 #a1afc9
    pub const CN_LAN_HUI: Self = Color::<u8>::CN_LAN_HUI.to_f32();
    // 其他f32颜色常量...
}

impl Color<f64> {
    /* 通用风格 */
    /// 国际黑 #000000
    pub const G_BLACK: Self = Color::<u8>::G_BLACK.to_f64();
    /// 国际白 #FFFFFF
    pub const G_WHITE: Self = Color::<u8>::G_WHITE.to_f64();
    /// 国际红 #FF0000
    pub const G_RED: Self = Color::<u8>::G_RED.to_f64();
    /// 国际绿 #00FF00
    pub const G_GREEN: Self = Color::<u8>::G_GREEN.to_f64();
    /// 国际蓝 #0000FF
    pub const G_BLUE: Self = Color::<u8>::G_BLUE.to_f64();
    /// 国际黄 #FFFF00
    pub const G_YELLOW: Self = Color::<u8>::G_YELLOW.to_f64();

    /* 中式风格 */
    /// 花萼绿 #014946
    pub const CN_CALYX_GREEN: Self = Color::<u8>::CN_CALYX_GREEN.to_f64();
    /// 蓝灰色 #a1afc9
    pub const CN_LAN_HUI: Self = Color::<u8>::CN_LAN_HUI.to_f64();

    // 其他f64颜色常量...
}

// Default Colors END..

// 仅为具体类型实现 Pod 和 Zeroable（可选）
unsafe impl bytemuck::Pod for Color<u8> {}
unsafe impl bytemuck::Zeroable for Color<u8> {}

unsafe impl bytemuck::Pod for Color<f32> {}
unsafe impl bytemuck::Zeroable for Color<f32> {}

unsafe impl bytemuck::Pod for Color<f64> {}
unsafe impl bytemuck::Zeroable for Color<f64> {}

impl Error for ColorError {}

pub trait HasMaxValue {
    const MAX_VALUE: Self;
}

impl HasMaxValue for u8 {
    const MAX_VALUE: Self = 255;
}
impl HasMaxValue for u16 {
    const MAX_VALUE: Self = 255;
}
impl HasMaxValue for u32 {
    const MAX_VALUE: Self = 255;
}
impl HasMaxValue for u64 {
    const MAX_VALUE: Self = 255;
}
impl HasMaxValue for i16 {
    const MAX_VALUE: Self = 255;
}
impl HasMaxValue for i32 {
    const MAX_VALUE: Self = 255;
}
impl HasMaxValue for i64 {
    const MAX_VALUE: Self = 255;
}
impl HasMaxValue for f32 {
    const MAX_VALUE: Self = 1.0;
}
impl HasMaxValue for f64 {
    const MAX_VALUE: Self = 1.0;
}
